package com.nulldev.util.web.YouTubeExtractor.util;

import static com.nulldev.util.manage.Macros.__assert;

import java.util.Arrays;

import com.nulldev.util.JVM.JVM;
import com.nulldev.util.VariableAPI.ArrayUtils;
import com.nulldev.util.data.Variables;
import com.nulldev.util.io.FastIO.FastIO;
import com.nulldev.util.manage.ObfuscatedCode;

public class YouTubePOTokenGenerator {

	private static final int K = 0;

	private static void __typed_array_set(final int[] arr, final int[] data, final int idx) {
		for (int i = 0; i < data.length; i++) {
			arr[idx + i] = data[i];
		}
	}

	private static void __typed_array_set(final int[] arr, final double[] data, final int idx) {
		for (int i = 0; i < data.length; i++) {
			arr[idx + i] = (int) data[i];
		}
	}

	@ObfuscatedCode(originalName = "qg", purpose = "Splits a string into it's seperate characters.")
	private static int[] split_to_chars(final String a) {
		final int[] b = new int[a.length()];
		int c = 0;
		int d = 0;
		for (; d < a.length(); d++) {
			int e = a.codePointAt(d);
			if (128 > e) {
				b[c++] = e;
			} else {
				if (2048 > e) {
					b[c++] = (e >> 6) | 192;
				} else {
					if (55296 == (e & 64512) && d + 1 < a.length() && 56320 == (a.codePointAt(d + 1) & 64512)) {
						e = 65536 + ((e & 1023) << 10) + (a.codePointAt(++d) & 1023);
						b[c++] = (e >> 18) | 240;
						b[c++] = ((e >> 12) & 63) | 128;
					} else {
						b[c++] = (e >> 12) | 224;
						b[c++] = (e & 63) | 128;
						b[c++] = (e & 63) | 128;
					}
				}
			}
		}
		return b;
	}

	@ObfuscatedCode(originalName = "j")
	private static int[] the_ugliest_function_you_have_ever_seen(final String _d) {
		final int[] b = split_to_chars(_d);

		__assert(118 < b.length, "DFO:Invalid");

		final int a = (int) Math.floor(System.currentTimeMillis() / 1E3);
		final double[] c = new double[]
			{ 255 * Math.random(), 255 * Math.random() };
		final double[] d = ArrayUtils.addAll(c, new double[]
			{ K & 255, 1d /* clientState */, (a >> 24) & 255, (a >> 16) & 255, (a >> 8) & 255, (a & 255) });

		final int[] a_array = new int[2 + d.length + b.length];

		a_array[0] = 34;
		a_array[1] = d.length + b.length;
		__typed_array_set(a_array, d, 2);
		__typed_array_set(a_array, b, 2 + d.length);

		final int[] b_sub = Arrays.copyOfRange(a_array, 2, a_array.length);

		final int _c = c.length;
		for (int _d1 = _c; _d1 < b.length; ++_d1)
			b_sub[_d1] ^= b_sub[_d1 % _c];

		{
			/* regenerate with changed values */

			final int[] output = new int[a_array.length];
			System.arraycopy(a_array, 0, output, 0, output.length);
			System.arraycopy(b_sub, 0, output, 2, output.length - 2);

			return output;
		}
	}

	private static final char[][] Zca = new char[5][];

	static {
		final char[] a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
		final String[] b = new String[]
			{ "+/=", "+/", "-_=", "-_.", "-_" };
		for (int c = 0; 5 > c; c++) {
			final char[] d = ArrayUtils.addAll(a, b[c].toCharArray());
			Zca[c] = d;
			for (int e = 0; e < d.length; e++) {
				// int f = d[e];
				// void 0 === ug[f] && (ug[f] = e)
			}
		}
	}

	private static String __JOIN_INTO(final int... chars) {
		final StringBuilder b = new StringBuilder(chars.length);
		for (final int c : chars)
			b.append((char) c);
		return b.toString();
	}

	@ObfuscatedCode(originalName = "rg")
	private static String generate_token(final int[] a, int b) {
		final char[] b_tables = Zca[b];

		/*
		 * Append one to the length here to workaround a JavaScript-ism that allows you
		 * to append values past the defined size
		 */
		String[] c = new String[(int) (Math.floor(a.length / 3)) + 1];

		final char d = (char) __OR(__ACCESS(b_tables, 64), '\0');
		int e = 0;
		int f = 0;
		for (; e < a.length - 2; e += 3) {
			int h = a[e];
			int l = a[e + 1];
			int m = a[e + 2];
			final int n = b_tables[h >> 2];

			h = b_tables[((h & 3) << 4) | (l >> 4)];
			l = b_tables[((l & 15) << 2) | (m >> 6)];
			m = b_tables[m & 63];
			c[f++] = __JOIN_INTO(n, h, l, m);
		}
		int n = 0;
		int m = d;

		switch (a.length - e) {
			case 2:
				n = a[e + 1];
				/* b_tables[(n & 15) << 2] */
				m = __OR(__ACCESS(b_tables, (n & 15) << 2), d);
			case 1:
				int a2 = a[e];
				c[f] = __JOIN_INTO(
						/* */
						b_tables[a2 >> 2],
						/* */
						b_tables[(a2 & 3) << 4 | n >> 4],
						/* */
						m, d);
		}

		return ArrayUtils.join(c, "");
	}

	private static Character __ACCESS(final char[] array, final int idx) {
		try {
			return array[idx];
		} catch (ArrayIndexOutOfBoundsException _ignored) {
			return null;
		}
	}

	@SuppressWarnings("unused")
	private static <T> T __ACCESS(final T[] array, final int idx) {
		try {
			return array[idx];
		} catch (ArrayIndexOutOfBoundsException _ignored) {
			return null;
		}
	}

	private static int __OR(final Character a, final Character b) {
		if (a == null) {
			return b;
		} else {
			return a;
		}
	}

	private static String hha(final int[] a) {
		return generate_token(a, 2);
	}

	public static String makeToken(final String visitorData) {
		Variables.requireNonNull(visitorData, "visitorData");
//		final Map<String, Object> very_ugly_json = FastMaps.fixedUniMap(new Object[][]
//			{
//					{ "c", "WEB" },
//					{ "cbr", "Chrome" },
//					{ "cbrVersion", URLUtils.USER_AGENT_VERSION },
//					{ "cos", "X11" },
//					{ "cplatform", "DESKTOP" },
//					{ "cplayer", "UNIPLAYER" },
//					{ "cver", YouTubeExtractorConstants.CLIENT_VERSION } });
		final int[] processed = the_ugliest_function_you_have_ever_seen(visitorData);
		return hha(processed);
	}

	public static void main(String[] args) {
		JVM.println("token: " + makeToken("CgtLdXRXV2JjQlFTVSjKkr2yBjIhCgJQTBIFRMLFBUWFwwYGRobHB0eHw4PIBAREiAX"));
		FastIO.get().flush();
		JVM.exit();
	}
}
